package lib.self.fresco;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.net.Uri;
import android.text.TextUtils;
import android.view.View;

import androidx.annotation.DrawableRes;
import androidx.core.content.ContextCompat;

import com.facebook.common.executors.CallerThreadExecutor;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.BaseDataSubscriber;
import com.facebook.datasource.DataSource;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.controller.AbstractDraweeController;
import com.facebook.drawee.controller.BaseControllerListener;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.drawee.view.SimpleDraweeView;
import com.facebook.imagepipeline.common.ResizeOptions;
import com.facebook.imagepipeline.core.ImagePipeline;
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
import com.facebook.imagepipeline.image.CloseableBitmap;
import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imagepipeline.postprocessors.IterativeBoxBlurPostProcessor;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import lib.self.util.autoFit.FitDpUtil;

/**
 * description: Fresco 工具类
 * author: Steven Xiao
 * date: 2018/5/15
 */
public class FrescoUtil {
    private static final String KFile = "file://";

    /**
     * 显示缩略图
     *
     * @param imageView      draweeView
     * @param url            url
     * @param resizeWidthDp  resizeWidth
     * @param resizeHeightDp resizeHeight
     */
    public static void showThumb(NetworkImageView imageView, String url, @DrawableRes int placeHolderImage, int resizeWidthDp, int resizeHeightDp) {
        if (TextUtils.isEmpty(url)) {
            return;
        } else {
            if (!url.startsWith(KFile)) {
                url = KFile + url;
            }
        }
        if (imageView == null) {
            return;
        }
        if (resizeHeightDp == 0) {
            resizeHeightDp = resizeWidthDp;
        }
        ImageRequest request = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url))
                .setResizeOptions(new ResizeOptions(FitDpUtil.dpToPx(resizeWidthDp, imageView.getContext()), FitDpUtil.dpToPx(resizeHeightDp, imageView.getContext())))
                .build();
        DraweeController controller = Fresco.newDraweeControllerBuilder()
                .setImageRequest(request)
                .setOldController(imageView.getController())
                .setControllerListener(new BaseControllerListener<>())
                .build();
        imageView.setController(controller);
        imageView.getHierarchy().setPlaceholderImage(placeHolderImage);
    }

    public static void showThumb(NetworkImageView imageView, String url, @DrawableRes int placeHolderImage, int resizeWidthDp) {
        showThumb(imageView, url, placeHolderImage, resizeWidthDp, 0);
    }

    /**
     * 以高斯模糊显示。
     *
     * @param draweeView View。
     * @param url        url.
     * @param iterations 迭代次数，越大越魔化。
     * @param blurRadius 模糊图半径，必须大于0，越大越模糊。
     */
    public static void showUrlBlur(SimpleDraweeView draweeView, String url, int iterations, int blurRadius) {
        try {
            Uri uri = Uri.parse(url);
            ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
                    .setPostprocessor(new IterativeBoxBlurPostProcessor(iterations, blurRadius))
                    .build();
            AbstractDraweeController controller = Fresco.newDraweeControllerBuilder()
                    .setOldController(draweeView.getController())
                    .setImageRequest(request)
                    .build();
            draweeView.setController(controller);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 加载图片成bitmap。
     *
     * @param imageUrl 图片地址。
     */
    public static void loadToBitmap(String imageUrl, ContextCompat context, BaseBitmapDataSubscriber mDataSubscriber) {
        ImageRequest imageRequest = ImageRequestBuilder
                .newBuilderWithSource(Uri.parse(imageUrl))
                .setProgressiveRenderingEnabled(true)
                .build();

        ImagePipeline imagePipeline = Fresco.getImagePipeline();
        DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage
                (imageRequest, context);
        dataSource.subscribe(mDataSubscriber, CallerThreadExecutor.getInstance());
    }

    /**
     * 保存图片到本地
     *
     * @param context
     * @param url
     * @param localSavePath
     */
    public static void SaveImageFromDataSource(Context context, String url, final String localSavePath) {
        ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url))
                .setProgressiveRenderingEnabled(true).build();

        DataSource<CloseableReference<CloseableImage>> dataSource = Fresco.getImagePipeline()
                .fetchDecodedImage(imageRequest, context);

        dataSource.subscribe(new BaseDataSubscriber<CloseableReference<CloseableImage>>() {
            @Override
            protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> source) {

            }

            @Override
            protected void onNewResultImpl(DataSource<CloseableReference<CloseableImage>> source) {
                CloseableReference<CloseableImage> reference = source.getResult();
                CloseableImage image = reference.get();

                if (image instanceof CloseableBitmap) {
                    CloseableBitmap closeableBitmap = (CloseableBitmap) image;//图片转为bitmap
                    Bitmap picBitmap = closeableBitmap.getUnderlyingBitmap();
                    saveBitmap(picBitmap, localSavePath);
                }

            }
        }, CallerThreadExecutor.getInstance());
    }

    /**
     * View 转换成 bitmap
     *
     * @param v
     * @return
     */
    public static Bitmap createBitmap(View v) {
        Bitmap bmp = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bmp);
        c.drawColor(Color.WHITE);
        v.draw(c);
        return bmp;
    }

    /**
     * 将bitmap保存到本地
     *
     * @param bitmap
     * @param localSavePath
     * @return
     */
    public static boolean saveBitmap(Bitmap bitmap, String localSavePath) {
        if (TextUtils.isEmpty(localSavePath)) {
            throw new NullPointerException("保存的路径不能为空");
        }

        File f = new File(localSavePath);
        if (f.exists()) {// 如果本来存在的话，删除
            f.delete();
        }
        try {
            f.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            FileOutputStream out = new FileOutputStream(f);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            out.flush();
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

}
